package com.gopay.bis.manager.bank.expay;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.unionpay.expay.UnionPayAdPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.businesses.ExPayService;

/**
 * 银联代扣报文组装
 * 
 * @author zhengxue
 * 
 */
public class UnionPayAdPayManager {
	@Resource(name = "unionPayConfig")
	private Map<String, String> unionPayConfig;
	
	@Resource(name = "bankIds")
	private Map<String,String> bankIds;
	
	@Resource(name = "unionPayAdPayServiceClient")
	private ExPayService unionPayAdPayServiceClient;
	
	/**
	 * 银联代扣认证接口
	 * 
	 * @param message
	 * @return
	 * @throws GopayException
	 */
	public Object certification(UnionPayAdPayMessage message)
			throws GopayException {
		message = buildCertificationMsg(message);
		BankLogUtils.printExPayManagerCertificationSendLog(message);
		UnionPayAdPayMessage resMsg = (UnionPayAdPayMessage) unionPayAdPayServiceClient
				.certification(message);
		resMsg.setOutStlmCd(message.getOutStlmCd()); // 为了日志输出
		BankLogUtils.printExPayManagerCertificationReturnLog(resMsg);
		return resMsg;
	}
	
	/**
	 * 平台发送短信验证码
	 * 
	 * @param message
	 * @return
	 * @throws GopayException
	 */
	public Object sendSms(UnionPayAdPayMessage message) throws GopayException {
		return null;
	}
	
	/**
	 * 平台发送支付请求
	 * 
	 * @param message
	 * @return
	 * @throws GopayException
	 */
	public Object payment(UnionPayAdPayMessage message) throws GopayException {
		message = buildPayMsg(message);
		BankLogUtils.printExPayManagerPaymentSendLog(message);
		UnionPayAdPayMessage resMsg = (UnionPayAdPayMessage) unionPayAdPayServiceClient
				.payment(message);
		resMsg.setOutStlmCd(message.getOutStlmCd()); // 为了日志输出
		BankLogUtils.printExPayManagerPaymentReturnLog(resMsg);
		return resMsg;
	}
	
	/**
	 * 平台发送查询请求
	 * 
	 * @param message
	 * @return
	 * @throws GopayException
	 */
	public Object query(UnionPayAdPayMessage message) throws GopayException {
		message = buildQueryMsg(message);
		BankLogUtils.printExPayManagerQuerySendLog(message);
		UnionPayAdPayMessage res = (UnionPayAdPayMessage) unionPayAdPayServiceClient
				.queryOrder(message);
		res.setOutStlmCd(message.getOutStlmCd()); // 为了日志输出
		BankLogUtils.printExPayManagerQueryReturnLog(res);
		return res;
	}
	
	/**
	 * 构建认证信息
	 * 
	 * @param message
	 * @return
	 */
	private UnionPayAdPayMessage buildCertificationMsg(UnionPayAdPayMessage message) {
		message.setSignMethod(unionPayConfig.get("CHINAPAYADPAY.SIGNMETHOD"));
		message.setAppSysId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.APPSYSID"));
		message.setCertNo(message.getIdentityCode()); // 证件号
		message.setCertType("01"); // 平台只支持身份证
		message.setDcType("0"); // 借记卡
		message.setUsrName(message.getCardHolder()); // 持卡人
		message.setCardCvn2(getDatas(message.getCvv2()));
		message.setCardExpire(getDatas(message.getAvailableDate()));
		message.setMobile(message.getMediaId());
		if(!message.getBank().equals("CMB")){
			message.setChannelId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.CHANNELID"));
			message.setValidWayId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.VALIDWAYID"));
		}else{
			message.setChannelId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.CMB.CHANNELID"));
			message.setValidWayId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.VALIDWAYID"));
		}
		StringBuffer plainMessage = new StringBuffer();
		plainMessage.append("appSysId=" + getDatas(message.getAppSysId() + "&"));
		//plainMessage.append("bizType=" + message.getBizType() + "&");
		plainMessage.append("cardCvn2=" + getDatas(message.getCardCvn2() + "&"));
		plainMessage.append("cardExpire=" + getDatas(message.getCardExpire() + "&"));
		plainMessage.append("cardNo=" +getDatas( message.getCardNo() + "&"));
		plainMessage.append("cardPhone=" + message.getMobile() + "&");
		plainMessage.append("certNo=" + getDatas(message.getCertNo() + "&"));
		plainMessage.append("certType=" + getDatas(message.getCertType() + "&"));
		plainMessage.append("channelId=" + getDatas(message.getChannelId() + "&"));
		plainMessage.append("dcType=" +getDatas( message.getDcType() + "&"));
		//plainMessage.append("email=" + message.getEmail() + "&");
		//plainMessage.append("merId=" + message.getMerId() + "&");
		//plainMessage.append("merName=" + message.getMerName() + "&");
		plainMessage.append("mobile=" + message.getMobile() + "&");
		//plainMessage.append("pin=" + message.getPin() + "&");
		plainMessage.append("save=false"  + "&");
		plainMessage.append("serviceType=1028"  + "&");
		plainMessage.append("usrName=" + getDatas(message.getUsrName() + "&"));
		plainMessage.append("validWayId=" + message.getValidWayId());
		message.setPlainMessage(plainMessage.toString());
		message.setBankUrl(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.URL"));
		message.setSignMethod(unionPayConfig.get("CHINAPAYADPAY.SIGNMETHOD"));
		
		// 贷记卡测试数据
		return message;
	}
	
	/**
	 * 构建支付信息
	 * 
	 * @param message
	 * @return
	 * @throws GopayException 
	 * @throws Exception
	 */
	private UnionPayAdPayMessage buildPayMsg(UnionPayAdPayMessage message) throws GopayException {
		message.setOrderNo(message.getBankOrderId());
		message.setTransAmt(message.getAmount().toString());
		message.setTransDate(message.getOrderDate().substring(0, 8));
		message.setCardType("0"); // 0表示卡
		message.setCertType("01"); // 平台只支持身份证
		message.setCertId(message.getIdentityCode()); // 证件号 
		
		StringBuffer plainMessage = new StringBuffer();
		message.setMerId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.MERID"));
		message.setAppSysId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.APPSYSID"));
		message.setGateId(unionPayConfig.get("CHINAPAY.AD.PAY.GATEID"));
		message.setTransType(unionPayConfig.get("CHINAPAY.AD.PAY.TRANSTYPE")); 
		message.setVersion(unionPayConfig.get("CHINAPAY.AD.PAY.VERSION"));
		message.setCuryId(unionPayConfig.get("CHINAPAY.AD.PAY.CURYID"));
		message.setTransAmt(getUnionPayAdPayAmount(message.getTransAmt()));
		message.setOpenBankId( bankIds.get(getDatas(message.getBank()) ));
		message.setCardCvn2(getDatas(message.getCvv2()));
		message.setCardExpire(getDatas(message.getAvailableDate()));
		String name = message.getCardHolder();
		name = gbEncoding(name);
		name = name.replaceAll("\\\\", "\\\\");
		message.setUsrName(message.getCardHolder());
		plainMessage.append(getDatas(message.getMerId() ));
		plainMessage.append( getDatas(message.getTransDate()));
		plainMessage.append(getDatas( message.getOrderNo()));
		plainMessage.append( getDatas(message.getTransType()) );
		plainMessage.append( message.getOpenBankId());
		plainMessage.append(getDatas( message.getCardType()) );
		plainMessage.append( getDatas(message.getCardNo()) );
		plainMessage.append(name);
		plainMessage.append( getDatas(message.getCertType()) );
		plainMessage.append(getDatas(message.getCertId()) );
		plainMessage.append(getDatas(message.getCuryId()) );
		plainMessage.append(  getDatas(message.getTransAmt()));
		plainMessage.append( getDatas(message.getPriv1()) );
		plainMessage.append(getDatas(message.getVersion()) );
		plainMessage.append( getDatas(message.getGateId()));
		message.setPlainMessage(plainMessage.toString());
		message.setBankUrl(unionPayConfig.get("CHINAPAY.AD.PAY.URL"));
		System.out.println(plainMessage.toString());
		return message;
	}
	
	/**
	 * 构建查询信息
	 * 
	 * @param message
	 * @return
	 */
	private UnionPayAdPayMessage buildQueryMsg(UnionPayAdPayMessage message) {
		message.setMerId(unionPayConfig.get("CHINAPAY.AD.CERTIFICATION.MERID"));
		message.setTransType(unionPayConfig.get("CHINAPAY.AD.PAY.TRANSTYPE")); 
		message.setVersion(unionPayConfig.get("CHINAPAY.AD.PAY.VERSION"));
		message.setOrderNo(message.getBankOrderId());
		StringBuffer plainMessage = new StringBuffer();
		plainMessage.append( message.getMerId() );
		plainMessage.append(message.getTransType());
		plainMessage.append(message.getBankOrderId());
		plainMessage.append( message.getTransDate() );
		plainMessage.append( message.getVersion());
		message.setPlainMessage(plainMessage.toString());
		message.setBankUrl(unionPayConfig.get("CHINAPAY.AD.QUERY.URL"));
		return message;
	}
	
	private String getDatas(String str){
		if(StringUtils.isNotBlank(str)){
			return str;
		}else{
			return "";
		}
	}
	
	private  String getUnionPayAdPayAmount(String amount) throws GopayException {
		amount = TransUtils.amountConvert2Fen(amount);
		if(amount.length()<=12){
			int num = 12-amount.length();
			for(int i=0;i<num;i++){
				amount = "0"+amount;
			}
			
		}else{
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6057);
		}
		return amount;
	}
	
	public static String gbEncoding(final String gbString) {
		char[] utfBytes = gbString.toCharArray();
		String unicodeBytes = "";
		for (int byteIndex = 0; byteIndex < utfBytes.length; byteIndex++) {
			String hexB = Integer.toHexString(utfBytes[byteIndex]);
			if (hexB.length() <= 2) {
				hexB = "00" + hexB;
			}
			unicodeBytes = unicodeBytes + "\\u" + hexB;
		}
		System.out.println("unicodeBytes is: " + unicodeBytes);
		return unicodeBytes;
	}

}
